Go back to manually stringifying resolve
authorAlex Crichton <alex@alexcrichton.com>
Fri, 1 Aug 2014 17:46:04 +0000 (10:46 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 1 Aug 2014 17:46:04 +0000 (10:46 -0700)
src/cargo/ops/cargo_generate_lockfile.rs

index e1c3c67d3e94196b7a1f12848ecdf39122c93b2e..0c43a1d35429f2bad0f28fb755d7d6386937f676 100644 (file)
@@ -4,14 +4,15 @@ use std::io::File;
 
 use serialize::{Encodable, Decodable};
 use toml::Encoder;
-use rstoml = toml;
+use toml = toml;
 
 use core::registry::PackageRegistry;
 use core::{MultiShell, Source, Resolve, resolver, Package, SourceId};
 use core::PackageId;
 use sources::{PathSource};
 use util::config::{Config};
-use util::{CargoResult, toml, human};
+use util::{CargoResult, human};
+use cargo_toml = util::toml;
 
 pub fn generate_lockfile(manifest_path: &Path,
                          shell: &mut MultiShell,
@@ -43,17 +44,6 @@ pub fn generate_lockfile(manifest_path: &Path,
     Ok(())
 }
 
-pub fn write_resolve(pkg: &Package, resolve: &Resolve) -> CargoResult<()> {
-    let mut e = Encoder::new();
-    resolve.encode(&mut e).unwrap();
-
-    let out = rstoml::Table(e.toml).to_string();
-    let loc = pkg.get_root().join("Cargo.lock");
-    try!(File::create(&loc).write_str(out.as_slice()));
-
-    Ok(())
-}
-
 pub fn update_lockfile(manifest_path: &Path,
                        shell: &mut MultiShell,
                        to_update: Option<String>) -> CargoResult<()> {
@@ -119,8 +109,63 @@ pub fn load_lockfile(path: &Path, sid: &SourceId) -> CargoResult<Option<Resolve>
 
     let s = try!(f.read_to_string());
 
-    let table = rstoml::Table(try!(toml::parse(s.as_slice(), path)));
-    let mut d = rstoml::Decoder::new(table);
+    let table = toml::Table(try!(cargo_toml::parse(s.as_slice(), path)));
+    let mut d = toml::Decoder::new(table);
     let v: resolver::EncodableResolve = Decodable::decode(&mut d).unwrap();
     Ok(Some(try!(v.to_resolve(sid))))
 }
+
+pub fn write_resolve(pkg: &Package, resolve: &Resolve) -> CargoResult<()> {
+    let mut e = Encoder::new();
+    resolve.encode(&mut e).unwrap();
+
+    let mut out = String::new();
+
+    // Note that we do not use e.toml.to_string() as we want to control the
+    // exact format the toml is in to ensure pretty diffs between updates to the
+    // lockfile.
+    let root = e.toml.find(&"root".to_string()).unwrap();
+
+    out.push_str("[root]\n");
+    emit_package(root.as_table().unwrap(), &mut out);
+
+    let deps = e.toml.find(&"package".to_string()).unwrap().as_slice().unwrap();
+    for dep in deps.iter() {
+        let dep = dep.as_table().unwrap();
+
+        out.push_str("[[package]]\n");
+        emit_package(dep, &mut out);
+    }
+
+    let loc = pkg.get_root().join("Cargo.lock");
+    try!(File::create(&loc).write_str(out.as_slice()));
+    Ok(())
+}
+
+fn emit_package(dep: &toml::Table, out: &mut String) {
+    out.push_str(format!("name = {}\n", lookup(dep, "name")).as_slice());
+    out.push_str(format!("version = {}\n", lookup(dep, "version")).as_slice());
+
+    dep.find(&"source".to_string()).map(|_| {
+        out.push_str(format!("source = {}\n", lookup(dep, "source")).as_slice());
+    });
+
+    dep.find(&"dependencies".to_string()).map(|s| {
+        let slice = s.as_slice().unwrap();
+
+        if !slice.is_empty() {
+            out.push_str("dependencies = [\n");
+
+            for child in s.as_slice().unwrap().iter() {
+                out.push_str(format!(" {},\n", child).as_slice());
+            }
+
+            out.push_str("]\n");
+        }
+        out.push_str("\n");
+    });
+}
+
+fn lookup<'a>(table: &'a toml::Table, key: &str) -> &'a toml::Value {
+    table.find(&key.to_string()).expect(format!("Didn't find {}", key).as_slice())
+}